﻿using System;
using Glue;
using Xunit;

namespace GlueTests.RelationContainerTests
{
    public class When_relating_towards_same_property_twice_from_different_source
    {
        private readonly Mapping<DomainPerson, GuiPerson> mapping;

        public class DomainPerson
        {
            public String FirstName { get; set; }
            public String LastName { get; set; }
            public String Name { get; set; }
            public DomainAddress Address { get; set; }
        }
        public class DomainAddress {public String City { get; set; }}
        
        public class GuiPerson
        {
            public String FirstName { get; set; }
            public String LastName { get; set; }
            public String Name { get; set; }
            public GuiAddress Address { get; set; }
        }
        public class GuiAddress { public String City { get; set; } }

        public When_relating_towards_same_property_twice_from_different_source()
        {
            mapping = new Mapping<DomainPerson, GuiPerson>();
        }

        [Fact]
        public void Should_throw_meaningful_exception_when_relating_twice_on_rightside_and_relations_are_TwoWays()
        {
            mapping.Relate(domain => domain.FirstName, gui => gui.Name);
            Assert.Throws(typeof(GlueException),() => mapping.Relate(domain => domain.LastName, gui => gui.Name));
        }

        [Fact]
        public void Should_throw_meaningful_exception_when_relating_twice_on_leftside_and_relations_are_TwoWays()
        {
            mapping.Relate(domain => domain.Name, gui => gui.FirstName);
            Assert.Throws(typeof(GlueException), () => mapping.Relate(domain => domain.Name, gui => gui.LastName));
        }

        [Fact]
        public void Should_accept_when_second_relation_on_RightSide_is_not_directed_towards_the_same_property()
        {
            mapping.Relate(domain=>domain.FirstName,gui=>gui.Name);
            mapping.RelateTowardsLeft(domain=>domain.LastName,gui=>gui.Name);
        }

        [Fact]
        public void Should_accept_when_second_relation_on_LeftSide_is_not_directed_towards_the_same_property()
        {
            mapping.Relate(domain => domain.Name, gui => gui.FirstName);
            mapping.RelateTowardsRight(domain => domain.Name, gui => gui.LastName);
        }

        [Fact]
        public void Should_throw_meaningful_exception_when_relating_twice_on_rightside_and_relations_are_TwoWays_and_is_simplified_nested_relation()
        {
            mapping.Relate(domain => domain.Address.City, gui => gui.Address.City);
            Assert.Throws(typeof(GlueException), () => mapping.Relate(domain => domain.LastName, gui => gui.Address.City));
        }

        [Fact]
        public void Should_throw_meaningful_exception_when_relating_twice_on_leftside_and_relations_are_TwoWays_and_is_simplified_nested_relation()
        {
            mapping.Relate(domain => domain.Address.City, gui => gui.Address.City);
            Assert.Throws(typeof(GlueException), () => mapping.Relate(domain => domain.Address.City, gui => gui.FirstName));
        }

        [Fact]
        public void Should_accept_when_second_relation_on_RightSide_is_not_directed_towards_the_same_property_and_is_simplified_nested_relation()
        {
            mapping.Relate(domain => domain.Address.City, gui => gui.Address.City);
            mapping.RelateTowardsLeft(domain => domain.LastName, gui => gui.Address.City);
        }

        [Fact]
        public void Should_accept_when_second_relation_on_LeftSide_is_not_directed_towards_the_same_property_and_is_simplified_nested_relation()
        {
            mapping.Relate(domain => domain.Address.City, gui => gui.Address.City);
            mapping.RelateTowardsRight(domain => domain.Address.City, gui => gui.FirstName);
        }
    }
}
